﻿using System;
using System.Text;
using System.Drawing;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public static partial class NativeAOT
{
    [UnmanagedCallersOnly(EntryPoint = "pqroot")]
    public static unsafe int pqroot(IntPtr x_ptr, double eps, IntPtr f_x_ptr)
    {
        double* xx = (double*)x_ptr.ToPointer();
        f_x = Marshal.GetDelegateForFunctionPointer<delegatefunc_x>(f_x_ptr);

        return pqroot(xx, eps);
    }

    /// <summary>
    /// 方程求根连分式法
    /// f(x)方程左端函数的函数名。
    /// </summary>
    /// <param name="xx">xx方程根初值。返回迭代终值。</param>
    /// <param name="eps">控制精度要求。</param>
    /// <returns>函数返回迭代次数。一次迭代最多作到七节连分式。本函数最多迭代20次。</returns>
    public static unsafe int pqroot(double* xx, double eps, int inter = 20)
    {
        int j, k, flag;
        double x0;
        double* b = stackalloc double[10];
        double* x = stackalloc double[10];
        double* y = stackalloc double[10];

        k = 0;
        x0 = *xx;
        flag = 0;
        while ((k < inter) && (flag == 0))
        {
            k = k + 1;
            j = 0;
            x[0] = x0;
            y[0] = f_x(x[0]);
            // 计算b[0]
            b[0] = x[0];
            j = 1;
            x[1] = x0 + 0.1;
            y[1] = f_x(x[1]);
            while (j <= 7)
            {
                // 计算b[j]
                funpqj(y, x, b, j);
                // 计算x[j+1]
                x[j + 1] = funpqv(y, b, j, 0.0);
                // 计算y[j+1]
                y[j + 1] = f_x(x[j + 1]);
                x0 = x[j + 1];
                if (Math.Abs(y[j + 1]) >= eps)
                {
                    j = j + 1;
                }
                else
                {
                    j = 10;
                }
            }
            if (j == 10)
            {
                flag = 1;
            }
        }
        *xx = x0;
        return (k);
    }

    /*
    // 方程求根连分式法例
      int main()
      { 
          int k;
          double x,eps,pqrootf(double);
          eps=0.0000001; x=1.0;
          k=pqroot(&x,eps,pqrootf);
          cout <<"迭代次数 = " <<k <<endl;
          cout <<"方程根为 x = " <<x <<endl;
          cout <<endl;
             //检验精度
    cout <<"检验精度 : f(x)=" <<pqrootf(x) <<endl;
          return 0;
      }
    // f(x)
      double pqrootf(double x)
      { 
          double y;
          y=x*x*(x-1.0)-1.0;
          return(y);
      }
    */
    /*
      double pqrootf(double x)
      { 
          double y;
          y=x*x+x-6.0;
          return(y);
      }
    */
    /*
      double pqrootf(double x)
      { 
          double y;
          y=exp(-x*x*x)-sin(x)/cos(x)+800;
          return(y);
      }
    */
}

